/*
 * Copyright (C) 2009 Luc Boudreau
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */
package com.encon.projecttracker.server.services.impl;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.log4j.Logger;

import com.encon.projecttracker.server.data.pojo.ConnectionType;
import com.encon.projecttracker.server.data.pojo.SavedConnection;
import com.encon.projecttracker.server.data.pojo.Session;
import com.encon.projecttracker.server.data.pojo.User;
import com.encon.projecttracker.server.services.DiscoveryService;
import com.encon.projecttracker.server.services.SessionService;
import com.encon.projecttracker.server.messages.Messages;

import org.springframework.util.Assert;

/**
 * Simple service implementation as a Spring bean.
 * @author Luc Boudreau
 */
public class SessionServiceImpl extends AbstractService
        implements SessionService
{

        Logger log = Logger.getLogger(this.getClass());





        private Map<String,Map<String, Session>> sessions = new ConcurrentHashMap<String, Map<String, Session>>();;





        private DiscoveryService discoveryService = null;



        public void afterPropertiesSet() throws Exception {
                Assert.notNull(this.discoveryService);
        }



        public String createNewSession(String userId)
        {
            this.validateUser(userId);

                String generatedId = String.valueOf(UUID.randomUUID());

                if (!sessions.containsKey(userId))
                        sessions.put(userId, new ConcurrentHashMap<String, Session>());

                sessions.get(userId).put(generatedId, new Session(generatedId));

                return generatedId;
        }




        public void releaseSession(String userId, String sessionId)
        {
            this.validateSession(userId, sessionId);
                
                sessions.get(userId).get(sessionId).destroy();
                sessions.get(userId).remove(sessionId);

                if (sessions.get(userId).size()==0)
                        sessions.remove(userId);
        }


        public Session getSession(String userId, String sessionId)
        {
            this.validateSession(userId, sessionId);
            return sessions.get(userId).get(sessionId);
        }



        public void deleteUserSessionVariable(String userId, String sessionId,
                String key)
        {
            this.validateSession(userId, sessionId);
                sessions.get(userId).get(sessionId)
                        .getVariables().remove(key);
        }



        public void saveUserSessionVariable(String userId, String sessionId,
                String key, Object value)
        {
            this.validateSession(userId, sessionId);
                sessions.get(userId).get(sessionId)
                        .getVariables().put(key, value);
        }




        public Object getUserSessionVariable(String userId, String sessionId,
                        String key)
        {
            this.validateSession(userId, sessionId);
                return sessions.get(userId).get(sessionId)
                        .getVariables().get(key);
        }


       



        



  


      


       
        public SavedConnection getConnection(String userId,
                String connectionId)
        {
            this.validateUser(userId);
            return this.userManager.getSavedConnection(userId, connectionId);
        }

        public void saveConnection(String userId, SavedConnection connection)
        {
            this.validateUser(userId);
        User user = this.userManager.getUser(userId);
        user.getSavedConnections().add(connection);
        this.userManager.updateUser(user);
    }

        public List<SavedConnection> getConnections(String userId)
        {
            this.validateUser(userId);
            List<SavedConnection> connections = new ArrayList<SavedConnection>();
            User user = this.userManager.getUser(userId);
            connections.addAll(user.getSavedConnections());
            return connections;
        }

     

        public void deleteConnection(String userId, String connectionName)
        {
            this.validateUser(userId);
            User user = this.userManager.getUser(userId);
            SavedConnection conn = getConnection(userId, connectionName);
            user.getSavedConnections().remove(conn);
            this.userManager.updateUser(user);
        }



        public void setDiscoveryService(DiscoveryService discoveryService) {
                this.discoveryService = discoveryService;
        }


        /**
         * Accessor. For testing purposes.
         * @return
         */
        protected Map<String,Map<String,Session>> getSessions() {
                return sessions;
        }



    public void validateSession(String userId, String sessionId)
            throws SecurityException {
        this.validateUser(userId);
        if (!sessions.containsKey(userId)
            || !sessions.get(userId).containsKey(sessionId))
            throw new SecurityException(
                Messages.getString("Services.InvalidSessionOrUserId")); //$NON-NLS-1$
    }



    public void validateUser(String userId) throws SecurityException
    {
        User user = this.userManager.getUser(userId);
        if (user==null)
            throw new SecurityException(
                Messages.getString("Services.InvalidSessionOrUserId")); //$NON-NLS-1$
    }
}
